/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package labbd_._projetofinal;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleTypes;

/**
 *
 * @author bimaoe
 */
public class Usuario {
	private OracleConnection conn;
	private String myemail;
	private BigDecimal mycpf;
	private String myname;

	public Usuario () {
		conn = null;
		myemail = null;
		myname = "Visitante";
	}
	/**
	 *	Método que cria um novo usuário
	 * @param in_conn
	 *	Conexão aberta com o banco de dados Oracle.
	 *	Método não fecha a conexão.
	 * @param in_cpf
	 * @param in_email
	 * @param in_nome
	 * @param in_senha
	 * @param in_rua
	 * @param in_numero
	 * @param in_cep
	 * @param in_uf
	 * @param in_cidade
	 * @param in_bairro
	 * @throws SQLException
	 */
	public static void novoUsuario (OracleConnection in_conn, BigDecimal in_cpf,
		String in_email, String in_nome, String in_senha, String in_rua,
		int in_numero, int in_cep, String in_uf, String in_cidade,
		String in_bairro) throws SQLException, Exception {

		String query = "begin pkg_usuario.proc_novousuario (?,?,?,?,?,?,?,?,?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall (query);
		Ocallstmt.setBigDecimal(1, in_cpf);
		Ocallstmt.setString (2, in_email);
		Ocallstmt.setString (3, in_nome);
		Ocallstmt.setString (4, in_senha);
		Ocallstmt.setString (5, in_rua);
		Ocallstmt.setInt (6, in_numero);
		Ocallstmt.setInt (7, in_cep);
		Ocallstmt.setString (8, in_uf);
		Ocallstmt.setString (9, in_cidade);
		Ocallstmt.setString (10, in_bairro);

		try {
			Ocallstmt.execute();
			in_conn.commit();
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
			in_conn.rollback();
			throw ex;
		} finally {
			Ocallstmt.close();
		}
	}
	public static String getEmailUsuario (OracleConnection in_conn, BigDecimal in_cpf) throws SQLException {
		String query = "begin ? := pkg_usuario.func_getEmailUsuario(?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall (query);
		Ocallstmt.registerOutParameter(1, java.sql.Types.VARCHAR);
		Ocallstmt.setBigDecimal (2, in_cpf);
		String ret = null;
		try {
			Ocallstmt.execute();
			ret = Ocallstmt.getString(1);
			return ret;
		} catch (SQLException e) {
			e.printStackTrace();
			throw e;
		} finally {
			Ocallstmt.close();
		}
	}

	/**
	 *
	 * @param in_oc
	 *	Conexao para a sessao do usuario
	 * @param in_email
	 * @param in_senha
	 * @throws SQLException
	 */
	public void loginEmail (OracleConnection in_oc, String in_email, String in_senha) throws SQLException {

		conn = in_oc;
		myemail = in_email;
		
		String query = "begin pkg_usuario.proc_loginUsuarioEmail(?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall (query);
		Ocallstmt.setString (1, in_email);
		Ocallstmt.setString (2, in_senha);

		try {
			System.err.println ("Logando");
			Ocallstmt.execute();

			query = "begin pkg_usuario.proc_getUsuarioPorEmail(?,?,?,?); end;";
			Ocallstmt = (OracleCallableStatement) conn.prepareCall (query);
			Ocallstmt.registerOutParameter(1, java.sql.Types.VARCHAR);
			Ocallstmt.registerOutParameter(2, java.sql.Types.VARCHAR);
			Ocallstmt.registerOutParameter(3, java.sql.Types.INTEGER);
			Ocallstmt.setString (4, in_email);
			Ocallstmt.execute();
			mycpf = new BigDecimal(Ocallstmt.getString(1));
			myname = Ocallstmt.getString(2);
			System.err.println("Creditos: "+Ocallstmt.getInt(3));
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
			throw ex;
		} finally {
			Ocallstmt.close();
		}
	}

	public void loginCPF (OracleConnection in_oc, BigDecimal in_cpf, String in_senha) throws SQLException {

		conn = in_oc;
		mycpf = in_cpf;
		String query = "begin pkg_usuario.proc_loginUsuarioCPF(?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall (query);
		Ocallstmt.setBigDecimal (1, in_cpf);
		Ocallstmt.setString (2, in_senha);

		try {
			System.err.println ("Logando");
			Ocallstmt.execute();

			query = "begin pkg_usuario.proc_getUsuarioPorCPF(?,?,?,?); end;";
			Ocallstmt = (OracleCallableStatement) conn.prepareCall (query);
			Ocallstmt.registerOutParameter(1, java.sql.Types.VARCHAR);
			Ocallstmt.registerOutParameter(2, java.sql.Types.VARCHAR);
			Ocallstmt.registerOutParameter(3, java.sql.Types.INTEGER);
			Ocallstmt.setBigDecimal(4, in_cpf);
			Ocallstmt.execute();
			myemail = Ocallstmt.getString(1);
			myname = Ocallstmt.getString(2);
			System.err.println("Creditos: "+Ocallstmt.getInt(3));

		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
			throw ex;
		} finally {
			Ocallstmt.close();
		}
	}
	
	public void logout () throws SQLException {
		if (conn != null) {
			System.err.println ("Deslogando");
		}

		conn = null;
		mycpf = null;
		myname = null;
		myemail = null;
	}
	public ArrayList<String> getMensagens () throws SQLException {
		ArrayList<String> ret = new ArrayList<String>();
		String query = "begin pkg_mensagem.proc_getMensagens(?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, OracleTypes.CURSOR);
		Ocallstmt.setBigDecimal(2, mycpf);
		Ocallstmt.execute();
		ResultSet rs = (ResultSet) Ocallstmt.getObject(1);
		while (rs.next()) {
			ret.add(rs.getString("CONTEUDO"));
		}
		return ret;
	}

	public static void addMensagem (OracleConnection in_conn, BigDecimal in_cpf, String in_mensagem) throws SQLException {
		String query = "begin pkg_mensagem.proc_addMensagem(?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall(query);
		Ocallstmt.setBigDecimal(1, in_cpf);
		Ocallstmt.setString(2, in_mensagem);
		Ocallstmt.execute();
	}
	/**
	 *
	 * @return
	 *	Quantidade de creditos do usuario
	 * @throws SQLException
	 */
	public int getCreditos () throws SQLException {

		String query = "begin ? := pkg_usuario.func_getCreditosUsuario(?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, java.sql.Types.INTEGER);
		Ocallstmt.setString(2, myemail);

		try {
			Ocallstmt.execute();
			return Ocallstmt.getInt(1);
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
		} finally {
			Ocallstmt.close();
		}
		return 0;
	}
	public BigDecimal getCPF () {
		return mycpf;
	}
	public String getName() {
		return myname;
	}

	public String getEmail(){
		return myemail;
        }
	/**
	 *
	 * @param in_idproduto
	 * @param in_nrooferta
	 * @return
	 *	ArrayList contendo o CPF dos usuarios que recomendaram a oferta ao usuario atual
	 */
	public ArrayList<BigDecimal> getRecomendacoes (int in_idproduto, int in_nrooferta) throws SQLException {
		ArrayList<BigDecimal> ret = new ArrayList<BigDecimal>();
		System.err.println ("Chamando para: "+mycpf+ " " + in_idproduto + " " + in_nrooferta);
		String query = "begin pkg_usuario.proc_recomendacoesUsuario (?,?,?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, OracleTypes.CURSOR);
		Ocallstmt.setBigDecimal (2, mycpf);
		Ocallstmt.setInt (3, in_idproduto);
		Ocallstmt.setInt (4, in_nrooferta);

		try {
			Ocallstmt.execute();
			ResultSet rs = (ResultSet) Ocallstmt.getObject(1);
			while (rs.next()) {
				System.err.println ("Add array "+rs.getString("CPF"));
				ret.add(new BigDecimal (rs.getString("CPF")));
			}
		} catch (SQLException e) {
			e.printStackTrace();
			throw e;
		} finally {
			Ocallstmt.close();
		}
		System.err.println ("Acabou");
		return ret;
	}

	//TODO fazer essa funcao retornar
	public void getHistorico (ArrayList out_compras, ArrayList out_presentes) throws SQLException {

		String query = "begin pkg_usuario.proc_historicoUsuario(?,?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall(query);
		Ocallstmt.registerOutParameter (1, OracleTypes.CURSOR);
		Ocallstmt.registerOutParameter (2,OracleTypes.CURSOR);
		Ocallstmt.setString (3, myemail);

		try {
			Ocallstmt.execute();
			ResultSet rscompras = (ResultSet) Ocallstmt.getObject(1);
			ResultSet rspresentes =  (ResultSet) Ocallstmt.getObject(2);

			System.out.println ("Histórico de compras");
			while (rscompras.next()) {
				System.out.println ("ID do cupom: "+rscompras.getInt("IDCUPOM")+
					" Numero da oferta: "+rscompras.getInt ("NROOFERTA")+
					" ID do produto: "+rscompras.getInt("IDPRODUTO")+
					" Data da compra: "+rscompras.getTime("DATACOMPRA"));
				out_compras.add(new Compra(rscompras.getInt("IDCUPOM"), rscompras.getInt("IDPRODUTO"),
						rscompras.getInt ("NROOFERTA"), rscompras.getDate("DATACOMPRA"), rscompras.getBlob("FOTO")));
			}
			System.out.println ("Histórico de presentes");
			while (rspresentes.next()) {
				System.out.println ("ID do cupom: "+rspresentes.getInt("IDCUPOM")+
					" Numero da oferta: "+rspresentes.getInt ("NROOFERTA")+
					" ID do produto: "+rspresentes.getInt("IDPRODUTO")+
					" Presenteador: "+rspresentes.getString("PRESENTEADOR"));

				out_presentes.add(new Presente(rspresentes.getInt("IDCUPOM"), rspresentes.getInt("IDPRODUTO"),
						rspresentes.getInt ("NROOFERTA"), rspresentes.getString("PRESENTEADOR"), rspresentes.getBlob("FOTO")));
			}
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage()+ex.getErrorCode());
			throw ex;
		} finally {
			Ocallstmt.close();
		}
	}

	public void compraOferta(int in_idproduto, int in_nrooferta, String formaPagamento) throws SQLException {

		String query = "begin pkg_oferta.proc_compraOferta (?,?,?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) conn.prepareCall(query);
		Ocallstmt.setInt(1, in_idproduto);
		Ocallstmt.setInt (2, in_nrooferta);
		Ocallstmt.setString (3, myemail);
		Ocallstmt.setString (4, formaPagamento);

		try {
			Ocallstmt.execute();
			System.err.println ("Compra bem sucedida");
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage()+ex.getErrorCode());
		} finally {
			Ocallstmt.close();
		}
	}
}
